在基础和进阶两篇文章中,讨论很多的理论知识,不知道你们怎么样,反正我是有点懵逼了,程序猿么,终归是要垒代码。来吧,我们用代码说话,看一看Dagger2到底是怎么个用法。
本文代码地址 Dagger2 示例 app-mvp-dagger2
示例中采用了MVP架构,使用Retrofit进行网络通信,并融入了 Rxjava RxBus 等。Dagger2 使用示例 在 app-mvp-dagger2 分支,请自行chekcout。
依赖标注
@Inject 标注
- @Inject 注解 BaseActivity 和 BaseFragment 的 Presenter 实例。
1 | public abstract class BaseActivity<T extends BasePresenter> extends SupportActivity implements BaseView { |
1 | public abstract class BaseFragment<T extends BasePresenter> extends SupportFragment implements BaseView { |
- @Inject标注依赖构造函数
1 |
|
1 |
|
@Moudle 工厂类
AppModule 提供全局依赖实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class AppModule {
private final ArchiApplication application;
public AppModule(ArchiApplication application){
this.application = application;
}
ArchiApplication provideApplicationContext(){
return application;
}
RetrofitHelper provideRetrofitHelper(RepositoriesService repositoriesService, UserInfoService userInfoService){
return new RetrofitHelper(repositoriesService, userInfoService);
}
}ActivityModule 为 Activity 提供 this 实例
1
2
3
4
5
6
7
8
9
10
11
12
public class ActivityModule {
private Activity mActivity;
public ActivityModule(Activity activity) {
this.mActivity = activity;
}
public Activity provideActivity() {
return mActivity;
}
}FragmentModule 为 Fragment 提供 Activity 实例
1
2
3
4
5
6
7
8
9
10
11
12
public class FragmentModule {
private Fragment fragment;
public FragmentModule(Fragment fragment) {
this.fragment = fragment;
}
public Activity provideActivity() {
return fragment.getActivity();
}
}
Component组织
Component 是依赖和被依赖的的桥梁,注入依赖。
AppComponent
- 定义 AppComponent 接口 ,@Singleton 标注,增加可读性
1 | @Singleton |
- 创建 AppComponent 单例
1
2
3
4
5
6
7
8
9
10
11
12
13
14public class ArchiApplication extends Application {
public static AppComponent appComponent;
public static AppComponent getAppComponent(){
if (appComponent == null) {
appComponent = DaggerAppComponent.builder()
.appModule(new AppModule(mInstance))
.httpModule(new HttpModule())
.build();
}
return appComponent;
}
}
ActivityComponent
自定义 ActivityScope 注解
1
2
3
4
(RetentionPolicy.RUNTIME)
public ActivityScope {
}定义 ActivityComponent 使用 @ActivityScope 标注
1
2
3
4
5
6
7
(dependencies = AppComponent.class,modules = ActivityModule.class)
public interface ActivityComponent {
Activity getActivity();
void inject(RepositoryActivity repositoryActivity);
}@ActivityScope 标注 Module 中的依赖实例提供方法
1
2
3
4
5
public Activity provideActivity() {
return mActivity;
}Build ActivityComponent实例
1
2
3
4
5
6
7
8
9
10
11
12public abstract class BaseActivity<T extends BasePresenter> extends SupportActivity implements BaseView {
...
protected ActivityComponent getActivityComponent(){
return DaggerActivityComponent.builder()
// 添加依赖 component
.appComponent(ArchiApplication.getAppComponent())
.activityModule(new ActivityModule(this))
.build();
}
}注入实例
1
2
3
4
5
6
7
8public class RepositoryActivity extends BaseActivity<RepositoryPresenter> implements RepositoryContract.View{
...
protected void initInject() {
getActivityComponent().inject(this);
}
...
}
FragmentComponent
自定义 FragmentComponent 注解
1
2
3
4
(RetentionPolicy.RUNTIME)
public FragmentScope {
}定义 FragmentComponent 使用 @FragmentScope 标注
1
2
3
4
5
6
7
8
(dependencies = AppComponent.class,modules = FragmentModule.class)
public interface FragmentComponent {
Activity getActivity();
void inject(MainFragment mainFragment);
}@FragmentScope 标注 Module 中的依赖实例提供方法
1
2
3
4
5
public Activity provideActivity() {
return fragment.getActivity();
}Build FragmentComponent
1
2
3
4
5
6
7
8
9
10
11
12public abstract class BaseFragment<T extends BasePresenter> extends SupportFragment implements BaseView {
...
protected FragmentComponent getFragmentComponent(){
return DaggerFragmentComponent.builder()
// 添加依赖 component
.appComponent(ArchiApplication.getAppComponent())
.fragmentModule(new FragmentModule(this))
.build();
}
}注入实例
1
2
3
4
5
6
7
8public class MainFragment extends BaseFragment<MainPresenter> implements MainContract.View {
...
protected void initInject() {
getFragmentComponent().inject(this);
}
...
}
RetrofitHelper 注入流程
MainPresenter 和 RepositoryPresenter 的构造函数中,有一个参数为 RetrofitHelper,根据Dagger2的注入流程,我们可以知道,RetrofitHelper会优先创建注入。
在 AppComponent 中管理的 Modules 中有一个 HttpModule,该 Module 主要作用是提供网络访问实例。
我们来看一下 RetrofitHelper 的注入流程。
- Presenter 的构造函数参数为 RetrofitHelper,所以 RetrofitHelper 会优先创建。
RetrofitHelper 构造函数参数为网络访问实例 RepositoriesService, UserInfoService。
1
2
3
4public RetrofitHelper(RepositoriesService repositoriesService, UserInfoService userInfoService){
this.repositoriesService = repositoriesService;
this.userInfoService = userInfoService;
}RepositoriesService 和 UserInfoService 实例由 HttpModule 提供
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
public class HttpModule {
/**
* 提供builder
* */
Retrofit.Builder provideRetrofitBuilder (){
return new Retrofit.Builder();
}
OkHttpClient.Builder provideOkHttpClientBuilder(){
return new OkHttpClient.Builder();
}
/**
* 提供客户端
* */
Retrofit provideRepositoriesRetrofit(Retrofit.Builder builder,OkHttpClient client){
return createRetrofit(builder, client, RepositoriesService.HOST);
}
Retrofit provideUserInfoRetrofit(Retrofit.Builder builder,OkHttpClient client){
return createRetrofit(builder, client, RepositoriesService.HOST);
}
OkHttpClient provideClient(OkHttpClient.Builder builder) {
return builder.connectTimeout(60000L, TimeUnit.MILLISECONDS)
.readTimeout(60000L, TimeUnit.MILLISECONDS)
.writeTimeout(60000L, TimeUnit.MILLISECONDS)
.build();
}
/**
* 提供API
* */
RepositoriesService provideRepositoriesService(@RespositoriesUrl Retrofit retrofit){
return retrofit.create(RepositoriesService.class);
}
UserInfoService provideUserInfoService(@UserInfoUrl Retrofit retrofit){
return retrofit.create(UserInfoService.class);
}
private Retrofit createRetrofit(Retrofit.Builder builder, OkHttpClient client, String host) {
return builder
.baseUrl(host)
.client(client)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
}
RetrofitHelper 完成创建后由 AppComponent 注入,为全局单一实例。
@Qualifier 使用
@Qualifier 的作用是使 Dagger2 避免依赖混乱。
定义 Qualifier 以 RespositoriesUrl 为例。
1
2
3
4
5
(RetentionPolicy.RUNTIME)
public RespositoriesUrl {
}使用 @RespositoriesUrl 标注依赖实例提供方法,该方法和其他方法的返回相同。
1
2
3
4
5
6
Retrofit provideRepositoriesRetrofit(Retrofit.Builder builder,OkHttpClient client){
return createRetrofit(builder, client, RepositoriesService.HOST);
}使用 @RespositoriesUrl 标注 provideRepositoriesRetrofit 的返回值
1
2
3
4
5
RepositoriesService provideRepositoriesService(@RespositoriesUrl Retrofit retrofit){
return retrofit.create(RepositoriesService.class);
}
author @ygwang